package com.leessy.r229.utils

import android.app.PendingIntent
import android.app.PendingIntent.FLAG_IMMUTABLE
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.util.Log
import android.widget.Toast
import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.FileIOUtils
import com.blankj.utilcode.util.ShellUtils
import com.leessy.r229.App
import com.leessy.r229.MService
import com.leessy.r229.config.Config
import com.leessy.r229.constants.Constants
import com.leessy.r229.kt.toJsonString
import com.leessy.r229.server.http.databean.AppInfoBean
import com.leessy.r229.server.http.databean.ConfigData
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.io.File
import kotlin.concurrent.thread


object AppUtil {
    //永久不被禁用和禁止安装的包名
    private const val BP = "com.leessy.r229,com.lc.settings,com.iflytek.speechcloud"

    private const val TAG = "AppUtil"

    //启动时的初始配置
    fun initConfig() {
        val intentFilter = IntentFilter(Intent.ACTION_PACKAGE_ADDED)
        intentFilter.addDataScheme("package")
        intentFilter.priority = 1000
        App.app.registerReceiver(object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                val pkg = intent.data?.schemeSpecificPart ?: return
                Log.d(TAG, "onReceive-action: ${intent.action}  pkg=$pkg")
                filterInstall(pkg)
            }
        }, intentFilter)

        //val string1 = Settings.Global.getString(App.app.contentResolver, APP_INSTALL_KEY)
        //val string = SPUtils.getInstance().getString(APP_INSTALL_KEY, "")
        //Log.d(TAG, "initConfig: $string1  && $string")
//        if (string1 != string) {
//            Settings.Global.putString(App.app.contentResolver, APP_INSTALL_KEY, string)
//        }
        init()
        checkDaemonProcess()
    }

    /**
     * 静默卸载应用
     *
     * @param path
     * @return
     */
    private fun uninstallApp1(path: String?, mContext: Context): Boolean {
        val broadcastIntent = Intent(mContext, InstallResultReceiver::class.java)
        val pendingIntent = PendingIntent.getBroadcast(
            mContext, 1,
            broadcastIntent, FLAG_IMMUTABLE
        )
        val packageInstaller = mContext.packageManager.packageInstaller
        packageInstaller.uninstall(path!!, pendingIntent.intentSender)
        return true
    }

    class InstallResultReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            Log.d(TAG, "onReceive:  静默卸载完成")
        }
    }

    fun uninstallApp(pkg: String) {
        if (BP.contains(pkg)) return
        uninstallApp1(pkg, App.app)
        val execCmd = ShellUtils.execCmd("pm uninstall $pkg", false)
        Log.d(TAG, "uninstallApp() called with: pkg = $pkg   execCmd=" + execCmd)
    }

    fun hideApp(pkg: String) {
        if (BP.contains(pkg)) return
        ShellUtils.execCmd("pm hide $pkg", false)
        if (!Config.hideapp!!.contains(pkg)) Config.hideapp = Config.hideapp + pkg + ","
        Log.d(TAG, "hideApp() called with: pkg = $pkg")
    }

    fun unhideApp(pkg: String) {
        ShellUtils.execCmd("pm unhide $pkg", false)
        Log.d(TAG, "unhideApp()---  called with: pkg = $pkg")
    }

    fun installApp(file: File, pkg: String? = null): Boolean {
        if (pkg == "com.leessy.r229") {//当前app安卓直接返回成功后再安装
            thread {
                Thread.sleep(1000)
                InstallSessionUtil.runInstallSession(file, App.app)
            }
            return true
        }
        val execCmd = ShellUtils.execCmd("pm install -r ${file.absolutePath}", false)
        Log.d(TAG, "installApp() called with: pkg = $file   execCmd=" + execCmd)
        if (execCmd.result != 0) {
            return InstallSessionUtil.runInstallSession(file, App.app)
        }
        return execCmd.result == 0
    }

    fun startApp(file: String) {
        if (BP.contains(file)) return
        try {
            AppUtils.launchApp(file)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    //配置了app白名单，但是不在列表内，新安装的直接卸载
    fun filterInstall(pkg: String) {
        //如果设备锁定或者自动锁定，则不能安装app
//        if (Config.deviceLock || MService.mService?.isAutoLock() == true ||//锁定状态不能安装app
        if (Constants.deviceLockAction == 2 ||//锁定状态不能安装app//////不再根据平台配置的超时自动锁定的日期来检测
            //如果安装控制开启，且安装列表不包含该app，则卸载
            (Config.installationCtrl && !Config.installationList!!.contains(pkg))
        ) {
            uninstallApp(pkg)
        //如果app启用控制开启，且启用列表不包含该app，则隐藏
        } else if (Config.appEnableCtrl && !Config.appEnableList!!.contains(pkg)) {
            hideApp(pkg)
        }
    }

    //判断是否安装守护进程，没有则安装
    fun checkDaemonProcess() {
        var packageInfo: PackageInfo? = null
        try {
            packageInfo = App.app.packageManager.getPackageInfo("com.lc.settings", 0)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        Log.d(TAG, "checkDaemonProcess: packageInfo --- $packageInfo")
        if (packageInfo == null) {
            val f = File(Constants.rootPath_Upgrade + "/npp.apk")
            val w = FileIOUtils.writeFileFromIS(f, App.app.assets.open("UserSettings.apk"))
            Log.d(TAG, "checkDaemonProcess: writeFileFromIS = $w")
            if (w) {
                InstallSessionUtil.runInstallSession(f, App.app)
            }
        } else {
            val intent = Intent()
            intent.component = ComponentName("com.lc.settings", "com.lc.settings.CheckService")
            App.app.startService(intent)
        }
        unhideApp("com.lc.settings")
    }

    fun getAllUserPkgStr(): String {
        var p = ""
        for (s in getAllUserPkg()) {
            p += "$s,"
        }
        return p
    }


    fun getAllAppInfo(): String {
        var p = ""
        for (s in getAllAppDetailInfo()) {
            p += "$s,"
        }
        return p
    }


    //获取所有后装app
    fun getAllUserPkg(): List<String> {
        var list = arrayListOf<String>()
        val pm: PackageManager = App.app.getPackageManager()
        val apps =
            pm.getInstalledApplications(PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS or PackageManager.GET_UNINSTALLED_PACKAGES)
        for (app in apps) {
            // 检查是否是系统应用或系统更新的应用
            val isSystemApp = (app.flags and ApplicationInfo.FLAG_SYSTEM) != 0
            val isUpdatedSystemApp = (app.flags and ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0
            if (!isSystemApp && !isUpdatedSystemApp && !BP.contains(app.packageName)) {
                // 这是一个后装应用
//                val appName = pm.getApplicationLabel(app).toString()
//                allPkg += "$packageName,"
                list.add(app.packageName)
            }
        }
        Log.d(TAG, "getAllUserPkg: " + list.toJsonString())
        return list
    }


    //获取所有后装app信息
//    fun getAllAppDetailInfo(): ArrayList<AppInfoBean> {
    fun getAllAppDetailInfo(): String {
        var list = arrayListOf<AppInfoBean>()
        val pm: PackageManager = App.app.packageManager
        val apps = pm.getInstalledApplications(PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS or PackageManager.GET_UNINSTALLED_PACKAGES)
        for (app in apps) {
            // 检查是否是系统应用或系统更新的应用
            val isSystemApp = (app.flags and ApplicationInfo.FLAG_SYSTEM) != 0
            val isUpdatedSystemApp = (app.flags and ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0
            if (!isSystemApp && !isUpdatedSystemApp && !BP.contains(app.packageName)) {
                // 这是一个后装应用
//                val appName = pm.getApplicationLabel(app).toString()
//                allPkg += "$packageName,"

                try {
                    val packageName = app.packageName
                    val packageInfo = pm.getPackageInfo(packageName, 0)
                    var appInfoBean = AppInfoBean()
                    appInfoBean.pgName = packageName
                    appInfoBean.appName = pm.getApplicationLabel(app).toString()
                    appInfoBean.appVer = if (packageInfo != null) packageInfo.versionName else ""
                    list.add(appInfoBean)
                }catch (e:Exception){
                    e.printStackTrace()
                }
            }
        }
        Log.d(TAG, "getAllUserPkg: " + list.toJsonString())
//        return list
        return list.toJsonString()
    }


//    fun getAllHideapp(): List<String> {
//        val pm: PackageManager = App.app.getPackageManager()
//        val installedApps = pm.getInstalledApplications(
//            PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS or PackageManager.GET_UNINSTALLED_PACKAGES
//        )
//    }

    //更新app配置
    fun updateConfig(data: ConfigData) {
        //todo 配置从锁定到非锁定状态，需要撤销所有禁用
        val deviceExpireUpdated = Config.deviceExpire != data.deviceExpire || Config.deviceExpireDay != data.deviceExpireDay
//        val lockupdated = !(Config.deviceAutoLockDate == data.deviceAutoLockDate && Constants.deviceLock == data.deviceLock)
        Log.v(TAG,"=Constants.deviceLock=${Constants.deviceLockAction}=data.deviceLock=${data.deviceLock}")
        val lockupdated = Config.deviceLock != data.deviceLock //去除根据平台配置的超时自动锁定的日期检测
        val appEnableUpdated =
            !(Config.appEnableCtrl == data.appEnableCtrl && Config.appEnableList == data.appEnableList)
        val installationUpdated =
            !(Config.installationCtrl == data.installationCtrl && Config.installationList == data.installationList)

        Log.d(
            TAG,
            "updateConfig: " + "deviceExpireUpdated=$deviceExpireUpdated\n" + "lockupdated=$lockupdated\n" + "appEnableUpdated=$appEnableUpdated\n" + "installationUpdated=$installationUpdated"
        )
        Config.deviceExpireDay = data.deviceExpireDay
        Config.deviceExpire = data.deviceExpire
        Config.deviceExpireMsg = "${data.deviceExpireMsg}"
        Config.deviceAutoLockDate = data.deviceAutoLockDate
        Config.deviceLock = data.deviceLock
        Config.deviceLockMsg = "${data.deviceLockMsg}"
        Config.appEnableCtrl = data.appEnableCtrl
        Config.appEnableList = data.appEnableList
        Config.installationCtrl = data.installationCtrl
        Config.installationList = data.installationList

        //更新显示
//        if (lockupdated || deviceExpireUpdated) MService.mService?.checkConfig()
        val allUserPkg = getAllUserPkg()
//        if (lockupdated || isAutoLock()) {
//            for (s in allUserPkg) {
//                hideApp(s)
//            }
//        }
        if (appEnableUpdated) {
            if (Config.appEnableCtrl) {
                //指定包名配置。如果之前不
                for (s in allUserPkg) {
                    if ("${Config.appEnableList}".contains(s)) {
                        unhideApp(s)
                    } else {
                        hideApp(s)
                    }
                }
            } else {
                for (s in allUserPkg) {
                    unhideApp(s)
                }
            }
        }
        if (installationUpdated && Config.installationCtrl) {
            //指定包名配置。如果之前不
            for (s in allUserPkg) {
                if ("${Config.installationList}".contains(s)) {
//                    unhideApp(s)
                } else {
                    uninstallApp(s)
                }
            }
        }

    }

    fun resetHideApp() {
        Log.d(TAG, "resetHideApp: ----- Config.appEnableCtr${Config.appEnableCtrl}")
        val allUserPkg = getAllUserPkg()
        if (Config.appEnableCtrl) {
            for (s in allUserPkg) {
                if ("${Config.appEnableList}".contains(s)) {
                    unhideApp(s)
                }
            }
        } else {
            for (s in allUserPkg) {
                unhideApp(s)
            }
        }
    }

    private fun init() {
        val allUserPkg = getAllUserPkg()
        Log.d(TAG, "init:   allUserPkg= $allUserPkg")
        //禁用启用在服务里面根据锁定状态初始化 resetHideApp
//        if (Config.appEnableCtrl) {
//            //指定包名配置。如果之前不
//            for (s in allUserPkg) {
//                if ("${Config.appEnableList}".contains(s)) {
//                    unhideApp(s)
//                } else {
//                    hideApp(s)
//                }
//            }
//        } else {
//            for (s in allUserPkg) {
//                unhideApp(s)
//            }
//        }
        if (Config.installationCtrl) {
            //指定包名配置。如果之前不
            for (s in allUserPkg) {
                if ("${Config.installationList}".contains(s)) {
//                    hideApp(s)
                } else {
                    uninstallApp(s)
                }
            }
        }
        checkEncipher()
    }

    private fun checkEncipher() {
        CoroutineScope(Dispatchers.IO).launch {
            //        if (Config.checkEncipher!!.isEmpty()) {
            Log.d(TAG, "checkEncipher: 延时前")
            delay(60000)//延迟1分钟
            Log.d(TAG, "checkEncipher: 延时后")
            val execCmd = ShellUtils.execCmd("test_tmel_drive", false)
            Log.d(TAG, "checkEncipher: $execCmd===successMsg=${execCmd.successMsg}==errorMsg=${execCmd.errorMsg}")
            if ("${execCmd.successMsg}".contains("OK") || "${execCmd.errorMsg}".contains("atmel_wake OK")) {
                Log.d(TAG, "checkEncipher: OK")
                Config.checkEncipher = "OK"
            } else {
                Config.checkEncipher = "ERROR"
                Log.d(TAG, "checkEncipher: ERROR")
            }
//        }
        }
    }
}
